home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk11 / cprof12 / profile.doc < prev    next >
Text File  |  1995-03-18  |  17KB  |  403 lines

  1. /*****************************************************************************
  2.  *                                                                           *
  3.  *                      C     P  R  O  F  I  L  E  R                         *
  4.  *                                                                           *
  5.  *               Copyright (c) 1987  by  Michael F. Purcell                  *
  6.  *                                                                           *
  7.  *                                                                           *
  8.  *  The author grants permission for the non-commercial distribution of this *
  9.  *  software, provided that this and other identifying information remains   *
  10.  *  intact.                                                                  *
  11.  *                                                                           *
  12.  *  .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    *
  13.  *                                                                           *
  14.  *  This software is provided "as-is" and carries with it no explicit or     *
  15.  *  implicit promise of support by the author.  Nor will the author be held  *
  16.  *  liable for any damages, real or imagined, which may result from the use  *
  17.  *  or abuse of this software.                                               *
  18.  *                                                                           *
  19.  *  .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    *
  20.  *                                                                           *
  21.  *                                                                           *
  22.  *  These programs profile the execution counts and function elapsed times   *
  23.  *  of standard C programs.  They are intended to be used for analyzing C    *
  24.  *  program performance, and possibly as a debugging aid.                    *
  25.  *                                                                           *
  26.  *                                                                           *
  27.  *  The author may be contacted via:                                         *
  28.  *                                                                           *
  29.  *     - People/Link: as 'ASTRO*NUT'                                         *
  30.  *                                                                           *
  31.  *     - CompuServe:  as '73647,1102'                                        *
  32.  *                                                                           *
  33.  *****************************************************************************/
  34.  
  35.  
  36.  
  37.     I. A request from the Author
  38.  
  39.        I would appreciate feedback from users of this program. Please
  40.        inform me of errors found, or any other interesting results.
  41.        If there is sufficient interest, I will make the source available.
  42.  
  43. |      This is version 1.2 of the program (Nov, 1987).
  44.  
  45.  
  46.    II. Background
  47.  
  48.        I wrote this program because I was unable to find its equivalent
  49.        in  the public domain.  There is another PD C profiler, but it is
  50.        specifically for Manx C executable modules.  Since I happen to
  51.        use Lattice C, I decided to write my own.  If the other profiler
  52.        can handle Lattice (I haven't tried it), then at the very least
  53.        you now have a choice of utilities.
  54.  
  55.  
  56.  
  57.   III. Arc file descriptions
  58.  
  59.        File        Description
  60.        ----        -----------
  61.  
  62.        profile         Executable for the source profiler
  63.        profrpt         Executable for the reporter
  64.        profile.doc     Documentation
  65.        profutl.o       Object module containing profiler run time functions.
  66.        sieve.c         A sample program for profiling.
  67.        p-sieve.c       The profiled source file.
  68.        p-sieve.rpt     The statement execution report for the sieve sample.
  69.        samptime.rpt    A sample function time report, from the profiler itself.
  70.  
  71.  
  72.    IV. Program Features
  73.  
  74.  
  75.        1.  Will report statement execution counts for C programs.
  76.  
  77.        2.  Will report accumulated elapsed time by function. 
  78.  
  79.        3.  Will report net elapsed time by function (time in a function,
  80.            excluding other profiled functions which it calls).
  81.  
  82.        4.  Allows full control over generated source names.
  83.  
  84.        5.  Provides run time access to current profile data by the instrumented
  85.            program.  This allows creation of intermediate data files when
  86.            evaluating different facilities within your program. 
  87.  
  88.        6.  Should work well for standard C programs.  This includes
  89.            Lattice C, Manx C, as well as Microsoft C for MS-DOS (statement
  90.            counts only).  
  91.  
  92.  
  93.  
  94.     V. Program Limitations
  95.  
  96.  
  97.        The source profiler utility is a very limited C parser.  The
  98.        most significant limitation is that it does NOT support the C pre-
  99.        processor facilities.  Therefore, if you use a 'define' to rename
  100.        a standard C data type, or part of a statement syntax, the profiler
  101.        may fail with an error message. You can examine the partial source
  102.        output to determine the cause of the problem.
  103.  
  104.        An example of this is if you use "#ifdef ignore_this" to exclude
  105.        a large comment block. Bracket the comment block with "/* ... */"
  106.        instead.  Conditionally excluded source will be handled properly
  107.        as long as the source is syntactically complete. Nested IFs with
  108.        some of the IF statements conditionally excluded may get syntax
  109.        errors when compiling. 
  110.  
  111.        Problems can also occur if you use TYPEDEFs for variables.
  112.        The parser tries to avoid this problem by assuming that if it finds
  113.        an unknown symbol where a declaration type is expected, and if the
  114.        symbol contains NO lowercase letters, then that symbol is either
  115.        a typedef or a macro.  Since the common convention is to make typedefs
  116.        all uppercase, the parser will work for the vast majority of C
  117.        programs.
  118.  
  119. |      The profiler uses the "onexit" function to trap program termination. If
  120. |      your program already uses this function, then the profiled version may
  121. |      not run correctly.
  122.  
  123.  
  124.    VI. Running the Source Profiler
  125.  
  126.  
  127.        The source profiler reads a sourcefile(s) and produces an instrumented
  128.        version for each source file.  The names for the new files are based
  129.        on the original names, with modifications controlled by options.
  130.        If your program actually consists of several separately linked modules,
  131.        then all of the source modules must be profiled at the same time.     
  132.        The form for running the instrumentation program is:
  133.  
  134.            profile <options> <src1> <src2> <src3> ...
  135.  
  136.         where:
  137.  
  138.            <options> can be
  139.  
  140.              -fxxx : this changes the front of the new source file node from
  141. |                    the default 'p_' to 'xxx'.
  142.  
  143.              -bxxx : this changes the back of the new source file node from
  144.                      the default '' to 'xxx'.
  145.  
  146.              -exxx : this changes the extension of the new source file node
  147.                      from the input file extension to 'xxx'.
  148.  
  149.              -pxxx : this changes the path of the new source file from the
  150.                      input file path to 'xxx' (100 characters max).
  151.  
  152.              -dxxx : this changes the disk drive of the new source file
  153.                      from the input file drive to 'xxx'.
  154.  
  155.              -xz   : this option is used to turn off either of the profiling
  156.                      options.  Both options are on by default.  'z' can be
  157.                      't' or 'c', where 't' turns off function timing and
  158.                      'c' turns off statement counts.
  159.  
  160.            <src1>... are the source files which constitute your program. They
  161. |                    do not need to be in any particular order, but the
  162. |                    module which contains "main()" MUST be included.
  163.  
  164.  
  165.         Examples:
  166.  
  167.            "profile myprog.c"
  168.  
  169. |             will produce "p_myprog.c" in the current directory.  Statement
  170.               counts and function timings are included.
  171.  
  172.            "profile -dram: -pprof -f -xt -b-p dev/pgm1.c dev/pgm2.c dev/pgm3.c"
  173.  
  174.               will produce "prof/pgm1-p.c", "prof/pgm2-p.c", and 
  175.               "prof/pgm3-p.c". Elapsed time by function will not be captured.
  176.               The files will be written to 'ram:' (note that the path 'prof'
  177.               should already be defined in the 'ram:' directory).
  178.  
  179.  
  180.        If the function timings option is 'on', the source profiler will produce
  181.        a file called "PROFFCN.XRF".  This is a list of the functions in your
  182.        program.  It will be used by the profile report program when creating
  183.        the function timings report.
  184.  
  185.  
  186.  
  187.   VII. Running your program
  188.  
  189.  
  190.        Take the output source files and compile them as usual.  The object
  191. |      module 'profutl.o' must be added when linking the final program.
  192.        Note: if you select the function timing option, you will get
  193.        'warning' messages from the C compiler for functions which are not
  194.        defined as 'void'.  This is not a problem, and you should ignore these
  195.        warnings.
  196.  
  197.  
  198.        Run the compiled program as usual.  When it exits it will produce a data
  199. |      file called "PROFILE.CTx", where 'x' is a number.  If your program has
  200.        dumped intermediate data then there will be a sequence of these data
  201.        files.  If you have requested function timings, then a series of files
  202. |      called "PROFILE.TIx" will also be produced.
  203.  
  204.  
  205.  
  206.  VIII. Running Profile Reporter
  207.  
  208.  
  209.        The profile reporter reads a data file, and any of the profiled source
  210.        files to produce a report(s) showing statement counts and function
  211.        times.
  212.  
  213.  
  214.     The form for running the report program is:
  215.  
  216.            profrpt <options> <src1> <src2> ...
  217.  
  218.         where:
  219.  
  220.            <options> can be
  221.  
  222. |            -cxxx : this changes the count data file name from
  223. |                    "PROFILE.CT1" to "xxx".
  224.  
  225.              -txxx : Get the timing data from 'xxx' rather than
  226. |                    "PROFILE.TI1".
  227.  
  228.              -fzzz : Get the function list used by the timing report from 'zzz'
  229.                      rather than "PROFFCN.XRF". 
  230.  
  231.              -xz   : this option is used to turn off either of the profile
  232.                      report options.  Both options are on by default.  'z' can
  233.                      be 't' or 'c', where 't' turns off the function timing
  234.                      report and 'c' turns off the statement count report.
  235.  
  236.  
  237.            <src1>  ... are any or all of the profiled source files composing
  238.                      the original program.
  239.  
  240.  
  241.         Examples:
  242.  
  243.            "profrpt p-myprog.c"
  244.  
  245. |              will read "PROFILE.CT1" with "p-myprog.c" to produce the
  246.                report file "p-myprog.rpt".  It will read "PROFFCN.XRF" and
  247. |              "PROFILE.TI1" to produce the report file "PROFTIME.RPT".
  248.  
  249. |          "profrpt -dPROFILE.CT3 -tPROFILE.TI3  p-prog1.c p-prog3.c"
  250.  
  251. |              will read "PROFILE.CT3" with "p-prog.c" and "p-prog3.c" to
  252.                produce the report files "p-prog1.rpt" and "p-prog3.rpt".
  253.                The function timings report will be produced using
  254. |              "PROFILE.TI3" and "PROFFCN.XRF".
  255.  
  256.            "profrpt -xc"
  257.  
  258. |              will read "PROFFCN.XRF" and "PROFILE.TI1" to produce the
  259.                report file "PROFTIME.RPT".  A statement count report will
  260.                not be produced.
  261.                
  262.  
  263.  
  264.        The output consists of a series of reports called "<srcx>.rpt".  The
  265.        report names correspond to the instrumented source file names.  The
  266.        report shows an execution count for each C executable statement. 
  267.        Declarations, etc., outside a function have a count of blanks.
  268.        Unexecuted statements within functions will have a count of zero.
  269.        The counts and statements are separated by a ':'.
  270.  
  271.        This report is based on the instrumented source file.  The report
  272.        program attempts to 'clean up' the output so it looks as much like
  273.        the original sourcefile as possible.  However, there will always be
  274.        some extraneous lines.  If you compare the "sieve.c" and "p-sieve.rpt"
  275.        files, you will see that the report looks quite reasonable.  
  276.  
  277.  
  278.        The timings report shows a list of decimal numbers and function names.
  279.        The column headings have the following meanings:
  280.  
  281.            "Count"       : The number of times this function was entered.
  282.  
  283.            "Grosstime"   : The total number of elapsed seconds charged to this
  284.                            function.  This will include time spent in functions
  285.                            called by this function.  If a function is called
  286.                            recursively, only the first occurrence will be used.
  287.                            As a result, the function 'main' will have a gross
  288.                            time very close to the elapsed time of the entire
  289.                            program. This value will be inaccurate if the program
  290.                            terminates without properly exiting the function
  291.                            (i.e., via an 'exit' statement). 
  292.  
  293.            "Nettime"     : The total number of elapsed seconds charged to this
  294.                            function, excluding calls to other application
  295.                            functions.  Therefore, this shows the time spent
  296.                            executing just this function's code.
  297.  
  298.            "Net %"       : This is the net time as a percentage of the total
  299.                            net time of all functions.
  300.  
  301.            "Function"    : The name of the function.
  302.  
  303.  
  304.        At the end of the report is the total of all the net time values.  This
  305.        should approximate the actual program elapsed time.
  306.  
  307.  
  308.        Remember that all times are based on ELAPSED time.  If you are doing
  309.        multiprocessing, or you have functions which wait for user input, then
  310.        the time values will be skewed accordingly.
  311.        
  312.  
  313.    IX. Overhead
  314.  
  315.  
  316.        The instrumented source files will be 30% to 100% larger than the
  317.        original source files.  This is very dependent on the grammatical
  318.        complexity of your program.
  319.  
  320.        The instrumented load modules will be 25% to 50% larger than the
  321.        originals.
  322.  
  323.        The execution times will be 5% to 70% longer.  This is also very
  324.        dependent on the original program complexity.  I have a structurally
  325.        simple astrophysics program which is mostly floating point calculations.
  326.        The overhead for it was negligible.  On the other hand, the overhead
  327.        for the sieve sample is 75%.  
  328.  
  329.  
  330.     X. Accessing Run Time Profile Data
  331.  
  332.  
  333. |      A function is included in the "profutl.o" object module which allows
  334.        you to access the current profile data.  The idea here is that a
  335.        complex program will have many different facilities, which you may
  336.        want to analyze separately.  Yet, you may not want (be able) to run your
  337.        program many times.  Therefore I have included a routine which will
  338.        either dump or clear the profile data.
  339.  
  340.        The definition of this function is:
  341.  
  342. |          "short _P_ACCESS(short)".
  343.  
  344.        The values to pass as parameters are predefined as:
  345.  
  346.            "_P_DUMP"  to create a new data file using the current data.  The
  347. |                     first files will be called "PROFILE.CT1" and
  348. |                     "PROFILE.TI1".  The second will be "...2" and so on.
  349.  
  350.            "_P_CLEAR" to clear the current data (presumably after having
  351.                       dumped the data).
  352.  
  353.        The value returned is nonzero if an error is detected.
  354.  
  355.        A dummy defined value called "_PROFILER_" is included in the new source
  356.        files to allow you to conditionally compile code which accesses the
  357.        profiler function.
  358.  
  359.        A typical example might be:
  360.  
  361.            #ifdef _PROFILER_
  362.  
  363.            if (_P_ACCESS(_P_DUMP)) exit(4);
  364.  
  365.            _P_ACCESS(_P_CLEAR);
  366.  
  367.            #endif
  368.  
  369.  
  370.  
  371.    XI. Misc.
  372.  
  373.  
  374. |      The programs were created using Lattice C release 4.00 under
  375.        AmigaDOS version 1.2.
  376.  
  377.  
  378.   XII. Versions
  379.  
  380.        V1.0 (09/11/87)
  381.  
  382.           Base version uploaded to People-Link (PLINK).
  383.  
  384.        V1.1 (10/17/87)
  385.  
  386.           Contains a minor fix to the source processor which corrects a
  387.           problem with subblocks and local variables.
  388.  
  389. |      V1.2 (11/03/87)
  390. |
  391. |         Cleaned up problems with short/long integers when porting to
  392. |         IBM MS-DOS.
  393. |
  394. |         Minor documentation corrections.
  395. |
  396. |         Fixed a parser error involving SIZEOF in decls.
  397. |
  398. |         Recompiled everything with Lattice C version 4.00.
  399. |
  400. |         Changed file names to be compatible with MS-DOS.
  401. |
  402. |         Recognizes "_main()" as well as "main()". (Just don't use both!)
  403.